/**
 * 文档解析服务 - 支持多种格式文档的文本提取和内容解析
 *
 * 开发人员：徐少洋
 * 开发时间：2025-11-08 至 2025-11-12
 * 模块职责：实现多种文档格式的文本提取功能，支持PDF、Word、文本等格式的文档解析
 *
 * 技术要点：
 * - Apache PDFBox PDF文档解析
 * - Apache POI Word文档解析
 * - 多格式文档统一处理接口
 * - 流式处理避免内存溢出
 * - 文件类型验证和异常处理
 *
 * 开发故事：负责文档解析服务的设计和实现，与AI分析服务深度配合，为财务文档的智能分析提供准确的文本内容提取能力。
 */
package com.pbl.ai;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Service
public class DocumentParseService {

    public String parseDocument(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            throw new IllegalArgumentException("文件名不能为空");
        }

        String fileExtension = getFileExtension(fileName).toLowerCase();
        
        switch (fileExtension) {
            case "pdf":
                return parsePdf(file);
            case "doc":
            case "docx":
                return parseWord(file);
            case "txt":
                return parseText(file);
            default:
                throw new IllegalArgumentException("不支持的文件类型: " + fileExtension);
        }
    }

    private String parsePdf(MultipartFile file) throws IOException {
        try (InputStream inputStream = file.getInputStream();
             PDDocument document = PDDocument.load(inputStream)) {
            
            PDFTextStripper stripper = new PDFTextStripper();
            return stripper.getText(document);
        }
    }

    private String parseWord(MultipartFile file) throws IOException {
        try (InputStream inputStream = file.getInputStream();
             XWPFDocument document = new XWPFDocument(inputStream)) {
            
            List<String> paragraphs = new ArrayList<>();
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                String text = paragraph.getText();
                if (text != null && !text.trim().isEmpty()) {
                    paragraphs.add(text.trim());
                }
            }
            
            return String.join("\n", paragraphs);
        }
    }

    private String parseText(MultipartFile file) throws IOException {
        try (InputStream inputStream = file.getInputStream()) {
            byte[] bytes = inputStream.readAllBytes();
            return new String(bytes, "UTF-8");
        }
    }

    private String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return "";
        }
        return fileName.substring(lastDotIndex + 1);
    }

    public boolean isSupportedFileType(String fileName) {
        if (fileName == null) return false;
        
        String extension = getFileExtension(fileName).toLowerCase();
        return extension.equals("pdf") || 
               extension.equals("doc") || 
               extension.equals("docx") || 
               extension.equals("txt");
    }
}
